﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.ComponentModel;

namespace NeonMika.EightTracks
{
    public class Mix
    {
        #region Varibales

        int id;
        int tracks_count;
        int duration;
        string name;
        bool published;
        string description;
        int plays_count;
        int likes_count;
        string slug;
        string path;
        Dictionary<CoverFormat, string> cover_urls;
        string restful_url;
        string[] tag_list_cache;
        DateTime first_published_at;
        bool liked_by_current_user;
        bool nsfw;
        User user;
        #endregion

        #region Properties

        public int TracksCount
        {
            get { return tracks_count; }
            set { tracks_count = value; }
        }

        public int Duration
        {
            get { return duration; }
            set { duration = value; }
        }

        public string BiggestSqCover
        {
            get { return CoverUrls.Keys.Contains(CoverFormat.sq500) ? CoverUrls[CoverFormat.sq500] : CoverUrls.Keys.Contains(CoverFormat.sq250) ? CoverUrls[CoverFormat.sq250] : CoverUrls.Keys.Contains(CoverFormat.sq133) ? CoverUrls[CoverFormat.sq133] : CoverUrls.Keys.Contains(CoverFormat.sq100) ? CoverUrls[CoverFormat.sq100] : CoverUrls.Keys.Contains(CoverFormat.sq72) ? CoverUrls[CoverFormat.sq72] : CoverUrls.Keys.Contains(CoverFormat.sq56) ? CoverUrls[CoverFormat.sq56] : ""; }
        }

        public string BiggestMaxCover
        {
            get { return CoverUrls.Keys.Contains(CoverFormat.max1024) ? CoverUrls[CoverFormat.max1024] : CoverUrls.Keys.Contains(CoverFormat.max250w) ? CoverUrls[CoverFormat.max250w] : CoverUrls.Keys.Contains(CoverFormat.max200) ? CoverUrls[CoverFormat.max200] : CoverUrls.Keys.Contains(CoverFormat.max133w) ? CoverUrls[CoverFormat.max133w] : ""; }
        }

        public string SmallestSqCover
        {
            get { return CoverUrls.Keys.Contains(CoverFormat.sq56) ? CoverUrls[CoverFormat.sq56] : CoverUrls.Keys.Contains(CoverFormat.sq72) ? CoverUrls[CoverFormat.sq72] : CoverUrls.Keys.Contains(CoverFormat.sq100) ? CoverUrls[CoverFormat.sq100] : CoverUrls.Keys.Contains(CoverFormat.sq133) ? CoverUrls[CoverFormat.sq133] : CoverUrls.Keys.Contains(CoverFormat.sq250) ? CoverUrls[CoverFormat.sq250] : CoverUrls.Keys.Contains(CoverFormat.sq500) ? CoverUrls[CoverFormat.sq500] : ""; }
        }

        public string SmallestMaxCover
        {
            get { return CoverUrls.Keys.Contains(CoverFormat.max133w) ? CoverUrls[CoverFormat.max133w] : CoverUrls.Keys.Contains(CoverFormat.max200) ? CoverUrls[CoverFormat.max200] : CoverUrls.Keys.Contains(CoverFormat.max250w) ? CoverUrls[CoverFormat.max250w] : CoverUrls.Keys.Contains(CoverFormat.max1024) ? CoverUrls[CoverFormat.max1024] : ""; }
        }

        public User User
        {
            get { return user; }
            set { user = value; }
        }
        public bool Nsfw
        {
            get { return nsfw; }
            set { nsfw = value; }
        }
        public bool LikedByCurrentUser
        {
            get { return liked_by_current_user; }
            set { liked_by_current_user = value; }
        }
        public DateTime FirstPublishedAt
        {
            get { return first_published_at; }
            set { first_published_at = value; }
        }
        public string[] TagListCache
        {
            get { return tag_list_cache; }
            set { tag_list_cache = value; }
        }
        public Dictionary<CoverFormat, string> CoverUrls
        {
            get { return cover_urls; }
            set { cover_urls = value; }
        }
        public string RestfulUrl
        {
            get { return restful_url; }
            set { restful_url = value; }
        }
        public string Slug
        {
            get { return slug; }
            set { slug = value; }
        }
        public string Path
        {
            get { return path; }
            set { path = value; }
        }
        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public bool Published
        {
            get { return published; }
            set { published = value; }
        }
        public string Description
        {
            get { return description; }
            set { description = value; }
        }
        public int PlaysCount
        {
            get { return plays_count; }
            set { plays_count = value; }
        }
        public int LikesCount
        {
            get { return likes_count; }
            set { likes_count = value; }
        }

        public int DurationMinutes
        {
            get { return duration/60; }
        }
        #endregion

        public Mix(XElement xml)
        {
            string element = "";

            element = "name";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
                Name = xml.Element(element).Value.ToString();

            element = "description";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
                Description = xml.Element(element).Value.ToString();

            element = "slug";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
                Slug = xml.Element(element).Value.ToString();

            element = "path";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
                Path = xml.Element(element).Value.ToString();

            element = "restful-path";
            RestfulUrl = xml.TryGetStringElement(element);

            element = "liked-by-current-user";
            LikedByCurrentUser = xml.TryGetBoolElement(element);

            element = "published";
            Published = xml.TryGetBoolElement(element);

            element = "plays-count";
            PlaysCount = xml.TryGetIntElement(element);

            element = "likes-count";
            LikesCount = xml.TryGetIntElement(element);

            element = "id";
            Id = xml.TryGetIntElement(element);

            CoverUrls = new Dictionary<CoverFormat, string>();
            foreach (XElement x in from cover in xml.Element("cover-urls").Descendants() select cover)
                switch (x.Name.LocalName)
                {
                    case "sq56":
                        CoverUrls.Add(CoverFormat.sq56, x.Value.ToString());
                        break;
                    case "sq72":
                        CoverUrls.Add(CoverFormat.sq72, x.Value.ToString());
                        break;
                    case "sq100":
                        CoverUrls.Add(CoverFormat.sq100, x.Value.ToString());
                        break;
                    case "sq133":
                        CoverUrls.Add(CoverFormat.sq133, x.Value.ToString());
                        break;
                    case "sq250":
                        CoverUrls.Add(CoverFormat.sq250, x.Value.ToString());
                        break;
                    case "sq500":
                        CoverUrls.Add(CoverFormat.sq500, x.Value.ToString());
                        break;
                    case "original":
                        CoverUrls.Add(CoverFormat.original, x.Value.ToString());
                        break;
                    case "max200":
                        CoverUrls.Add(CoverFormat.max200, x.Value.ToString());
                        break;
                    case "max133w":
                        CoverUrls.Add(CoverFormat.max133w, x.Value.ToString());
                        break;
                    case "max250w":
                        CoverUrls.Add(CoverFormat.max250w, x.Value.ToString());
                        break;
                    case "max1024":
                        CoverUrls.Add(CoverFormat.max1024, x.Value.ToString());
                        break;

                }

            element = "tag-list-cache";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
                TagListCache = xml.Element(element).Value.ToString().Replace("&amp;", "&").Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

            FirstPublishedAt = new DateTime();
            element = "first-published-at";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
            {
                string[] datetime = xml.Element(element).Value.ToString().Split('T');
                string[] date = datetime[0].Split('-');
                string[] time = datetime[1].Split(':');
                FirstPublishedAt = new DateTime(Int32.Parse(date[0]), Int32.Parse(date[1]), Int32.Parse(date[2]), Int32.Parse(time[0]), Int32.Parse(time[1]), Int32.Parse(time[2].Remove(time[2].Length - 1)));
            }

            element = "user";
            if (xml.Element(element) != null && xml.Element(element).Attribute("nil") == null)
                User = new User(xml.Element(element));
            else
                User = null;

            element = "tracks-count";
            TracksCount = xml.TryGetIntElement(element);

            element = "duration";
            Duration = xml.TryGetIntElement(element);
        }
    }
}
